﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using Flux.Data;
using Flux.Data.Layers;
using Flux.Data.Maps;
using Flux.Editor.Extensions;
using Flux.Editor.Messaging;

namespace Flux.Editor.Controls
{
	public partial class LayerManagerPanel
	{
		#region Dependency Properties

		public static readonly DependencyProperty MapProperty = DependencyProperty.Register("Map", typeof (Map), typeof (LayerManagerPanel), new PropertyMetadata(OnMapChanged));
		public Map Map
		{
			get { return (Map) GetValue(MapProperty); }
			set { SetValue(MapProperty, value); }
		}

		#endregion

		#region Initialization

		public LayerManagerPanel()
		{
			InitializeComponent();
			if (this.IsInDesignMode()) return;
			RegisterMessages();
		}

		private void RegisterMessages()
		{
			App.Messenger.Register(Tokens.RefreshLayersPanel, Refresh);
			App.Messenger.Register(Tokens.SelectLayer, SelectLayer);
		}
		
		#endregion

		#region Events

		private static void OnMapChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			var panel = ((LayerManagerPanel)d);
			panel.Refresh();
		}

		private void AddTileLayerClick(object sender, RoutedEventArgs e)
		{
			AddTileLayer();
		}

		#endregion

		#region Methods

		public void Refresh(object message = null)
		{
			layerTree.Items.Clear();

			if (Map == null) return;

			foreach (var layer in Map.Layers)
			{
				var layerLeaf = CreateLeaf(layer.Name, "/Resources\\FluxFile.png", layer);
				layerTree.Items.Add(layerLeaf);
			}

			SelectLayer(App.SelectedLayer);
		}

		private TreeViewItem CreateLeaf(string header, string iconUri, object associatedObject = null)
		{
			var panel = new StackPanel
			{
				Orientation = Orientation.Horizontal
			};
			var img = new Image
			{
				Source = new BitmapImage(new Uri(iconUri, UriKind.RelativeOrAbsolute))
			};
			var text = new TextBlock
			{
				Text = header,
				Margin = new Thickness(4, 0, 0, 0)
			};
			panel.Children.Add(img);
			panel.Children.Add(text);

			var ret = new TreeViewItem
			{
				Header = panel,
				IsExpanded = true,
				Tag = associatedObject
			};
			ret.MouseLeftButtonUp += LeafLeftButtonUp;

			return ret;
		}

		private void LeafLeftButtonUp(object sender, MouseButtonEventArgs mouseButtonEventArgs)
		{
			var leaf = (TreeViewItem) sender;
			var layer = (ILayer) leaf.Tag;
			App.SelectedLayer = layer;
		}


		private ContextMenu CreateContextMenu(string header, object associatedObject)
		{
			var ret = new ContextMenu();

			if (associatedObject == null)
			{
				switch (header)
				{
					case "Maps":
						ret.Items.Add(CreateContextMenuItem("Add New Map", Tokens.AddNewMap));
						ret.Items.Add(CreateContextMenuItem("Add Existing Map", Tokens.AddExistingMap));
						break;
					case "Tilesets":
						ret.Items.Add(CreateContextMenuItem("Add New Tileset", Tokens.AddNewTileset));
						break;
				}
			}
			else
			{
				if (associatedObject is Project)
				{
					return null;
				}
			}

			return ret;
		}

		private TextBlock CreateContextMenuItem(string header, Tokens messageToken)
		{
			var ret = new TextBlock
			{
				Text = header,
				Tag = messageToken
			};
			ret.MouseLeftButtonDown += (s, e) => App.Messenger.Send(((TextBlock)s).Tag, s);
			return ret;
		}
		
		#endregion

		#region Actions

		private void AddTileLayer(object message = null)
		{
			App.Messenger.Send(Tokens.AddTileLayer, null);
		}

		private void SelectLayer(object message = null)
		{
			if (message == null) return;
			var layer = (ILayer) message;

			ClearSelectedItems();

			foreach (var item in layerTree.Items)
			{
				var treeViewItem = ((TreeViewItem) item);
				var leaf = (ILayer)treeViewItem.Tag;
				if (layer.Id == leaf.Id)
				{
					layerTree.SelectTreeViewItem(treeViewItem);
				}
			}
			App.SelectedLayer = layer;
		}

		public void ClearSelectedItems()
		{
			foreach (TreeViewItem item in layerTree.Items)
			{
				item.IsSelected = false;
			}
		}

		#endregion

		
	}
}
